package com.waqu.common.utils.waqu;


import org.apache.commons.lang3.StringUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * waquID生成工具类
 * 排除各种靓号规则
 * Created by zhengcunwen on 2016/6/12.
 */
public class WaquIdGenerator {

    // 靓号过滤类型正则，如AABBCD，符合数字有112234，336627等
    public static final    String ABCABC = "^(\\d{3})\\1$";
    public static final    String AABBCC = "^(\\d)\\1(\\d)\\2(\\d)\\3$";
    public static final    String AAXBBX = "^(\\d)\\1\\d(\\d)\\2\\d$";
    public static final    String LOVE6S = "^(520|521|1314|3344)\\d+$";


    public static final    String ABCABCX = "^(\\d{3})\\1\\d$";
    public static final    String ABABABC = "^(\\d{2})\\1\\1\\d$";
    public static final    String AABBCCX = "^(\\d)\\1(\\d)\\2(\\d)\\3\\d$";
    public static final    String XAABBCC = "^\\d(\\d)\\1(\\d)\\2(\\d)\\3$";
    public static final    String AAABBBC = "^(\\d)\\1\\1(\\d)\\2\\2\\d$";
    public static final    String CAAABBB = "^\\d(\\d)\\1\\1(\\d)\\2\\2$";
    public static final    String AAAXBBB = "^(\\d)\\1\\1\\d(\\d)\\2\\2$";


    // 靓号过滤相同连续数字的种子
    public static final String[] seeds_3 = {"111","222","333","444","555","666","777","888","999","000"};
    public static final String[] seeds_4 = {"1111","2222","3333","4444","5555","6666","7777","8888","9999","0000"};
    public static final String[] seeds_5 = {"11111","22222","33333","44444","55555","66666","77777","88888","99999","00000"};
    public static final String[] seeds_6 = {"111111","222222","333333","444444","555555","666666","777777","888888","999999","000000"};

    // 靓号中 4位、5位、7顺子
    public static final String[] specialNumbers_4 = {"1234","2345","3456","4567","5678","6789","9876","8765","7654","6543","5432","4321"};
    public static final String[] specialNumbers_5 = {"12345","23456","34567","45678","56789","98765","87654","76543","65432","54321"};
    public static final String[] specialNumbers_6 = {"123456","234567","345678","456789","987654","876543","765432","654321"};
    public static final String[] specialNumbers_7 = {"1234567","2345678","3456789","9876543","8765432","7654321"};



    /**
     *
     * 按照靓号规则，自动排除靓号，生成普通娃趣ID
     * 目前从6位数字开始
     * @param start 起始数字
     * @return
     */
    public static Integer generateNormalWaquId(Integer start){
        Integer waquId = null;
        int minId = 100000;
        int maxId = 9999999;

        if(start == null || start < minId){
            return null;
        }

        for(int i = start;i <= maxId;i++){
            // 字符串中包含1-2种数字
            if (isDuplicateCount(String.valueOf(i))) {
                continue;
            }

            // 通用规则排除，顺子号-递增
            if(isOrderNumer(String.valueOf(i))){
                continue;
            }

            if(isSameChars(String.valueOf(i))){
                continue;
            }

            // 指定格式类型判断
            if(isCustomStyleNumber(String.valueOf(i))){
                continue;
            }
            waquId = i;
            break;
        }
        return waquId;
    }



    /**
     * 批量生产娃趣号
     * @param start
     *        起始值
     * @param size
     *        批量生产的数量
     * @return
     */
    public static List<Integer> batchGenerateNormalWaquId(Integer start,Integer size){
        int minId = 100000;
        int maxId = 9999999;

        if(start == null || start < minId){
            return null;
        }
        if(size == null || size == 0){
            return null;
        }

        List<Integer> results = new ArrayList<Integer>();

        for(int i = start;i <= maxId;i++){

            // 字符串中包含1-2种数字
            if (isDuplicateCount(String.valueOf(i))) {

                continue;
            }


            // 通用规则排除，顺子号-递增
            if(isOrderNumer(String.valueOf(i))){
                continue;
            }

            if(isSameChars(String.valueOf(i))){
                continue;
            }

            // 指定格式类型判断
            if(isCustomStyleNumber(String.valueOf(i))){
                continue;
            }

            results.add(i);

            // 如果list的尺寸符合给定长度，break循环
            if(results.size() == size){
                break;
            }
        }
        return results;
    }


    /**
     * 批量生产靓号
     * @param start
     *        起始值
     * @return
     */
    public static List<Integer> batchGenerateBeautifulWaquId(Integer start){
        int minId = 100000;
        int maxId = 9999999;

        if(start == null || start < minId){
            return null;
        }


        List<Integer> results = new ArrayList<Integer>();

        for(int i = start;i <= maxId;i++){

            // 字符串中包含1-2种数字
            if (isDuplicateCount(String.valueOf(i))) {
                results.add(i);
                continue;
            }


            // 通用规则排除，顺子号-递增
            if(isOrderNumer(String.valueOf(i))){
                results.add(i);
                continue;
            }

            if(isSameChars(String.valueOf(i))){
                results.add(i);
                continue;
            }

            // 指定格式类型判断
            if(isCustomStyleNumber(String.valueOf(i))){
                results.add(i);
                continue;
            }

            /*// 如果list的尺寸符合给定长度，break循环
            if(results.size() == size){
                break;
            }*/
        }
        return results;
    }




    /**
     * 排除顺子号，4~7位顺子
     * @param srcNumber
     * @return
     */
    public static boolean isOrderNumer(String srcNumber){
        boolean result = false;

        if(traverseSeeds(specialNumbers_4,srcNumber)
                || traverseSeeds(specialNumbers_5,srcNumber)
                || traverseSeeds(specialNumbers_6,srcNumber)
                || traverseSeeds(specialNumbers_7,srcNumber)){
            result = true;
        }
        return result;
    }


    /**
     *
     * 判断是否包含相同数字
     * @param srcNumber
     *        需要判断的数字
     * @return
     */
    public static boolean isSameChars(String srcNumber){
        boolean result = false;

        if(StringUtils.isBlank(srcNumber)){
            return result;
        }


        if(srcNumber.length() == 6){
            if(traverseSeeds(seeds_3,srcNumber) || traverseSeeds(seeds_4,srcNumber) || traverseSeeds(seeds_5,srcNumber)){
                result = true;
            }
        }else if(srcNumber.length() == 7){
            if(traverseSeeds(seeds_4,srcNumber) || traverseSeeds(seeds_5,srcNumber) || traverseSeeds(seeds_6,srcNumber)){
                result = true;
            }
        }
        return result;
    }


    /**
     * 字符串中包含1-2种数字
     * @param src
     * @return
     */
    public static boolean isDuplicateCount(String src){
        boolean result = false;

        if(StringUtils.isBlank(src)){
            return result;
        }

        if(getNotDuplicateCount(src) == 1 || getNotDuplicateCount(src) == 2){
            result = true;
        }

        return result;
    }

    private static boolean traverseSeeds(String[] seeds,String src){
        boolean result = false;
        for(String s:seeds){
            if(src.indexOf(s) > -1){
                result = true;
                break;
            }
        }
        return result;
    }

    /**
     * 得到房间号数字长度，重复的合并
     * @param src
     * @return
     */
    public static int getNotDuplicateCount(String src){
        Map<String,Integer> counter = new HashMap();
        for (int i = 0; i < src.length(); i++) {
            String temp = String.valueOf(src.charAt(i));
            counter.put(temp,1);
        }
        return counter.size();
    }


    /**
     * 判断是否是生日号码（19开头的）
     * @param src
     * @return
     */
    public static boolean isBirthDayNumber(String src){
        if(StringUtils.isBlank(src)){
            return false;
        }

        if(src.length() != 6){
            return false;
        }
        return src.startsWith("19");
    }


    /**
     * 判断给定格式的数字格式
     * @param src
     * @return
     */
    public static boolean isCustomStyleNumber(String src){
        boolean result = false;
        if(src.length() == 6){
            if(matcherRegx(ABCABC,src)
                    || matcherRegx(AABBCC,src)
                    || matcherRegx(AAXBBX,src)
                    || matcherRegx(LOVE6S,src)){
                result = true;
            }
        }else if(src.length() == 7){

            if(matcherRegx(ABCABCX,src)
                    || matcherRegx(ABABABC,src)
                    || matcherRegx(AABBCCX,src)
                    || matcherRegx(XAABBCC,src)
                    || matcherRegx(AAABBBC,src)
                    || matcherRegx(CAAABBB,src)
                    || matcherRegx(AAAXBBB,src)
                    || matcherRegx(LOVE6S,src)){
                result = true;
            }
        }

        return result;
    }




    /**
     * 编译正则
     * @param regx
     * @param src
     * @return
     */
    private static boolean matcherRegx(String regx,String src){
        Pattern p = Pattern.compile(regx);
        Matcher m  = p.matcher(src);

        return m.matches();
    }



    private static void writeIntoFile(List<Integer> rooms){
        try {
            File file = new File("D:\\room2.txt");

            if(!file.exists()){
                file.createNewFile();
            }
            BufferedWriter out = new BufferedWriter(new FileWriter(file, true));
            for (Integer i:rooms) {
                out.write(String.valueOf(i));
                out.newLine();
            }
            out.close();
            out = null;
            file = null;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        //System.out.println(getNotDuplicateCount("678965"));
        //System.out.println(isDuplicateCount("331333"));

        //System.out.println(isBirthDayNumber("119133"));
       // System.out.println(isSpecialNumber("521325"));

 /*       Pattern p = Pattern.compile(CAABB);
        Matcher m  = p.matcher("61133");

        System.out.println(m.matches());*/

      /*  generateNormalRoomId(null);
        System.out.println("-----over----------");*/

        //1
        //String AAAAAA = "";

        //2
        //String AAAAAB = "^(\\d)\\1\\1\\1\\1\\d$";
        //String BAAAAA = "^\\d(\\d)\\1\\1\\1\\1$";
        //String AAAABB = "^(\\d)\\1\\1\\1(\\d)\\2$";
        //String BBAAAA = "^(\\d)\\1(\\d)\\2\\2\\2$";
        //String BAAAAB = "";
        //String AAABBB = "^(\\d)\\1\\1(\\d)\\2\\2$";
        //String ABCDEF = "";

        //3
        //String FEDCBA = "";
        //String AABAAB = "^(\\d)\\1\\d$";       //?
        //String ABABAB = "^(\\d{2})\\1\\1$";
        //String AAAABA = "";
        //String ABAAAA = "";
        //String AAAABC = "^(\\d)\\1\\1\\1\\d{2}$";
        //String BCAAAA = "^\\d{2}(\\d)\\1\\1\\1$";
        //String BAAAAC = "^\\d(\\d)\\1\\1\\1\\d$";

        //4
        //String ABCABC = "^(\\d{3})\\1$";
        //String AAABAA = "";
        //String AABAAA = "";
        //String AAABBA = "";
        //String ABBAAA = "";
        //String AABBCC = "^(\\d)\\1(\\d)\\2(\\d)\\3$";

        //5
        //String AAABBC = "^(\\d)\\1\\1(\\d)\\2\\d$";
        //String AAACBB = "^(\\d)\\1\\1\\d(\\d)\\2$";
        //String CAAABB = "^\\d(\\d)\\1\\1(\\d)\\2$";
        //String CBBAAA = "^\\d(\\d)\\1(\\d)\\2\\2$";
        //String AAABAB = "";
        //String ABABBB = "";

        //6
        //String AAABCD = "";
        //String BCDAAA = "";
        //String BCAAAD = "";
        //String ABBBCA = "";

        //7
        //String ABAABB = "";
        //String AABBAB = "";
        //String BAABBA = "";
        //String XABCDE = "";
        //String ABCDEX = "";
        //String XEDCBA = "";
        //String EDCBAX = "";

        //8


        //9  四顺
        //String LOVE6S = "";
        //String LOVE6S = "^(520|521|1314|3344)\\d+$";




        //System.out.println(matcherRegx(AAAAAB,"111112"));
/*        System.out.println(matcherRegx(BAAAAA,"211111"));
        System.out.println(matcherRegx(AAAABB,"333399"));
        System.out.println(matcherRegx(BBAAAA,"339999"));
        System.out.println(matcherRegx(AAABBB,"333999"));*/
        //System.out.println(matcherRegx(AABAAB,"112"));
        //System.out.println(matcherRegx(ABABAB,"121212"));

/*        System.out.println(matcherRegx(ABCABC,"352352"));
        System.out.println(matcherRegx(AABBCC,"112233"));
        System.out.println(matcherRegx(AAABBC,"555221"));
        System.out.println(matcherRegx(AAACBB,"555233"));
        System.out.println(matcherRegx(CAAABB,"211122"));
        System.out.println(matcherRegx(CBBAAA,"211222"));
        System.out.println(matcherRegx(LOVE6S,"52122322"));*/

       /* String ABCABCX = "^(\\d{3})\\1\\d$";
        String ABABABC = "^(\\d{2})\\1\\1\\d$";
        String AABBCCX = "^(\\d)\\1(\\d)\\2(\\d)\\3\\d$";
        String XAABBCC = "^\\d(\\d)\\1(\\d)\\2(\\d)\\3$";
        String AAABBBC = "^(\\d)\\1\\1(\\d)\\2\\2\\d$";
        String CAAABBB = "^\\d(\\d)\\1\\1(\\d)\\2\\2$";
        String AAAXBBB = "^(\\d)\\1\\1\\d(\\d)\\2\\2$";

        System.out.println(matcherRegx(ABCABCX,"1231231"));
        System.out.println(matcherRegx(AABBCCX,"1122441"));
        System.out.println(matcherRegx(XAABBCC,"3112244"));
        System.out.println(matcherRegx(CAAABBB,"2111444"));
        System.out.println(matcherRegx(AAABBBC,"1114443"));
        System.out.println(matcherRegx(ABABABC,"1212124"));
        System.out.println(matcherRegx(AAAXBBB,"2221555"));
*/
        System.out.println(new WaquIdGenerator().generateNormalWaquId(100000));
        /*System.out.println(matcherRegx(AAAXBBB,"1112000"));*/

        long start = System.currentTimeMillis();
        //writeIntoFile(batchGenerateNormalWaquId(1000000,999999));
        //writeIntoFile(batchGenerateBeautifulWaquId(1000000,9999999));
 /*       writeIntoFile(batchGenerateBeautifulWaquId(100000));
        System.out.println(System.currentTimeMillis() - start);*/
    }
}
